import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class AdvancedTicketSaleSystem{
	enum AMOUNTS{RELEASED,MAX,BUYER}
	static final long MS=1000;
	static int waitTime=1;
	static int[] amounts;
	static LinkedList<AdvancedBuyer> advancedBuyers;
	static LinkedList<Ticket> tickets;
	static ReentrantLock lock;
	static Condition condition;

	public static void main(String[] args) {
		init();
		while (true){
			for(int i=0,finishCount=0;
				finishCount< advancedBuyers.size();
				i=(i+1)% advancedBuyers.size()) {
				if (advancedBuyers.get(i).trialFinished)
					finishCount++;
				else finishCount = 0;
			}
			addTickets();
			System.out.println("已补好票");
			for(AdvancedBuyer advancedBuyer:advancedBuyers)
				if(advancedBuyer.ticket==null) {
					advancedBuyer.restart();
				}
		}
	}
	static void init(){
		String[] prompt={"请输入初始放票数","请输入最大放票数","请输入购票人数",};
		advancedBuyers=new LinkedList<>();
		tickets=new LinkedList<>();
		amounts=new int[prompt.length];

		System.out.println("**欢迎使用进阶版抢票模拟系统**");
		while (true){
			for (int i = 0; i < prompt.length; i++)
				while ((amounts[i] = GoldfishReader.readInt(prompt[i])) <= 0)
					System.out.println("请输入正数");
			if(amounts[AMOUNTS.RELEASED.ordinal()]>amounts[AMOUNTS.MAX.ordinal()])
				System.out.println("放票过量");
			else if(amounts[AMOUNTS.MAX.ordinal()]>amounts[AMOUNTS.BUYER.ordinal()])
				System.out.println("计划放票过量");
			else break;
		}

		while (tickets.size()<amounts[AMOUNTS.RELEASED.ordinal()]) try{
			tickets.add(new Ticket(
					(int) (Math.random() *amounts[AMOUNTS.MAX.ordinal()] )
			));
		}catch (Exception ignored){}

		while (advancedBuyers.size()<amounts[AMOUNTS.BUYER.ordinal()])
			advancedBuyers.add(new AdvancedBuyer(
					advancedBuyers.size()+1
			));

		lock=new ReentrantLock(true);
		condition=lock.newCondition();

		System.out.println("票已经印刷完毕,"+waitTime+"秒后发售");
		try{Thread.sleep(waitTime * MS);}
		catch (Exception e){}

		for (AdvancedBuyer advancedBuyer:advancedBuyers)
			advancedBuyer.start();
	}
	static synchronized Ticket sell(){
		if(tickets==null)	return null;
		else if (tickets.isEmpty())	return null;
		else return tickets.removeFirst();
//		try{
//			lock.lock();
//
//		}finally {
//			condition.notifyAll();
//			lock.unlock();
//		}
	}
	static void addTickets(){
		int addTickets;
		if (amounts[AMOUNTS.RELEASED.ordinal()]
				>=amounts[AMOUNTS.MAX.ordinal()]) {
			System.out.println("票已售完");
			System.exit(0);
		}
		while (true){
			addTickets = GoldfishReader.readInt("请输入补票数量************************");
			if(addTickets<=0) System.exit(0);
			else if (addTickets+amounts[AMOUNTS.RELEASED.ordinal()]
				>amounts[AMOUNTS.MAX.ordinal()])
				System.out.println("补票过多");
			else {
				if (addTickets+amounts[AMOUNTS.RELEASED.ordinal()]
					==amounts[AMOUNTS.MAX.ordinal()]) {
					System.out.println("票已售完");
				}
				for (int i=0;i<addTickets;){
					try {
						tickets.add(new Ticket(
								(int)(Math.random()*amounts[AMOUNTS.MAX.ordinal()])
						));
					}catch (Exception e){	i--;}
					finally{				i++;}
				}
				amounts[AMOUNTS.RELEASED.ordinal()] += addTickets;
				break;
			}
		}
	}
	static boolean allReleased(){
		if(amounts==null)return false;
		if(amounts.length<=3) return false;
		return amounts[AMOUNTS.RELEASED.ordinal()]
				==amounts[AMOUNTS.MAX.ordinal()];
	}
}
class AdvancedBuyer extends BasicBuyer {
	boolean trialFinished;
	public synchronized void restart(){
		this.trialFinished=false;
	}
	public AdvancedBuyer(int num) {
		super(num,2);
		finished = false;
		trialFinished = false;
		trial = 0;
	}

	@Override
	public void run() {
		while (true){
			while (trialFinished) {
				try {Thread.sleep(this.speed);}catch (Exception e){}
			}
			while (true) synchronized (System.out)//buy ticket
			{
				System.out.println(this.num + "号顾客");
				try {
					ticket = AdvancedTicketSaleSystem.sell();
					if (ticket != null) {
						System.out.println("抢到座位" + ticket.seatNum);
						trialFinished=true;
						finished = true;
						break;
					}
					else if (++trial >= maxTrial) {
						trialFinished = true;
						System.out.println("算了，先不试了");
						break;
					}
					else System.out.println("没抢到，待会再试");
				} catch (IllegalMonitorStateException e) {
					System.out.println("系统繁忙，再等会吧");
				}
			}
			if (finished)break;
			else if (AdvancedTicketSaleSystem.allReleased()) {
				System.out.println("没票了，不抢了");
				break;
			}
			else {
				trial=0;
				trialFinished = true;
			}
		}
	}
}
